package com.learning.rpc.rpc.protocol.lrpc.handler;

import com.learning.rpc.common.serialize.Serialization;
import com.learning.rpc.remoting.Handler;
import com.learning.rpc.remoting.RpcChannel;
import com.learning.rpc.rpc.Invocation;
import com.learning.rpc.rpc.Invoker;
import com.learning.rpc.rpc.Response;

/**
 * ClassName: LrpcServerHandler
 * Description: LRPC 协议的服务端处理器
 * Date: 2022/5/16 17:29 【需求编号】
 *
 * @author Sam Sho
 * @version V1.0.0
 */
public class LrpcServerHandler implements Handler {

    /**
     * 读取数据
     *
     * @param rpcChannel rpcChannel
     * @param message    Invocation
     * @throws Exception
     */
    @Override
    public void onReceive(RpcChannel rpcChannel, Object message) throws Exception {
        Invocation invocation = (Invocation) message;
        System.out.println("收到 Invocation 信息：" + invocation);

        // 发起方法调用
        // 发出数据 -- response
        Response response = new Response();
        try {
            // 调用目标 接口实现类
            Object result = getInvoker().invoke(invocation);
            response.setRequestId(invocation.getId());
            response.setStatus(200);
            response.setContent(result);
            System.out.println("服务端执行结果：" + result);
        } catch (Throwable e) {
            response.setStatus(99);
            response.setContent(e.getMessage());
            e.printStackTrace();
        }
        // 发送数据
        byte[] responseBody = getSerialization().serialize(response);

        // 写回数据
        rpcChannel.send(responseBody);
    }

    @Override
    public void onWrite(RpcChannel rpcChannel, Object message) throws Exception {

    }

    private Invoker invoker;
    private Serialization serialization;

    public void setInvoker(Invoker invoker) {
        this.invoker = invoker;
    }

    public Invoker getInvoker() {
        return this.invoker;
    }

    public void setSerialization(Serialization serialization) {
        this.serialization = serialization;
    }

    public Serialization getSerialization() {
        return this.serialization;
    }
}
